package net.peelmeagrape.hibernate.collections;

import net.peelmeagrape.hibernate.xmlgen.XmlAttribute;
import net.peelmeagrape.hibernate.xmlgen.XmlElement;
import net.peelmeagrape.hibernate.xmlgen.ChildElement;
import net.peelmeagrape.hibernate.xmlgen.DefaultFromGenericType;
import net.peelmeagrape.hibernate.*;

import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * Collection values of many-to-many type.
 * A <em>many to many association</em> requires a dedicated collection table
 * with a foreign key column or columns.
 * Very important note: If the foreign key column of a
 * {@link net.peelmeagrape.hibernate.collections.ManyToMany} association is declared NOT NULL, you must declare the
 * {@link net.peelmeagrape.hibernate.collections.Key} mapping not-null="true" or use a bidirectional association with
 * the collection mapping marked inverse="true". See
 * <a href="{@docRoot}/reference/en/html/collections.html#collections-bidirectional">Bidirectional associations</a>
 * for more info.
 */
@Retention(RUNTIME)
        @XmlElement(name="many-to-many")
        public @interface ManyToMany
{
    @ChildElement(0) Meta[] meta() default {};

    @ChildElement(1) Column[] columnMapping() default {};

    @ChildElement(2) Filter[] filters() default {};

    /**
     * The type of the entity this collection contains.
     */
    @XmlAttribute("class") @DefaultFromGenericType(-1) Class[] targetClass() default {};

    @XmlAttribute String node() default "";

    @XmlAttribute("embed-xml") boolean embedXml() default true;

    @XmlAttribute("entity-name") String entityName() default "";

    /**
     * The name of the element foreign key column.
     */
    @XmlAttribute String column() default "";

    @XmlAttribute String formula() default "";

    /**
     * Specifies how cached identifiers that reference missing rows will be handled:
     * ignore will treat a missing row as a null association.
     */

    @XmlAttribute("not-found") NotFoundSetting notFound() default NotFoundSetting.EXCEPTION;

    @XmlAttribute OuterJoinSetting outerJoin() default OuterJoinSetting.AUTO;

    @XmlAttribute LazySetting[] lazy() default {};

    /**
     * enables outer-join or sequential select fetching for this association.
     * This is a special case; for full eager fetching (in a single SELECT)
     * of an entity and its many-to-many relationships to other entities,
     * you would enable join fetching not only of the collection itself,
     * but also with this attribute on the many-to-many nested element.
     */
    @XmlAttribute FetchSetting[] fetch() default {};

    @XmlAttribute("foreign-key") String foreignKey() default "";

    /**
     * Enable the DDL generation of a unique constraint for the foreign-key column.
     * This makes the association multiplicity effectively one to many.
     */
    @XmlAttribute boolean unique() default false;

    @XmlAttribute String where() default "";
}
